package com.stu.utils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisUtils<T extends Serializable> {

	// public RedisClient redisClient=RedisClient. getInstance();
	public static Jedis jedis = null;
	public ObjectsTranscoder<T> objTranscoder = new ObjectsTranscoder<T>();
	public ListTranscoder<T> listTranscoder = new ListTranscoder<T>();
	private static JedisPool pool;

	static {
		jedis = getJedis();
	}

	public void set(String key, Object value) {
		jedis.set(key.getBytes(), objTranscoder.serialize(value));
	}

	public T get(String key) {
		return objTranscoder.deserialize(jedis.get(key.getBytes()));
	}
	 
	public void zadd(String key,double score,Object value){
		jedis.zadd(key.getBytes(), score, objTranscoder.serialize(value));
	}
	
	public List<T> lrange(String key){
		List<byte[]> lb=jedis.lrange(key.getBytes(), 0, -1);
		List<T>dataList=new ArrayList<T>();
		for(byte[]b:lb){
			T t=objTranscoder.deserialize(b);
			dataList.add(t);
		}
		return dataList;
	}
	
	public List<T> brpop(String key,int timeout){
		List<byte[]> lb=jedis.brpop(timeout, key.getBytes());
		List<T>dataList=new ArrayList<T>();
		for(byte[]b:lb){
			T t=objTranscoder.deserialize(b);
			dataList.add(t);
		}
		return dataList;
	}
	
	public Long lpush(String key,Object value){
		return jedis.lpush(key.getBytes(), objTranscoder.serialize(value)); 
	}
	
	public void del(String key){
		jedis.del(key.getBytes());
	}
	
	public List<T> zrevrange(String key,long start,long end){
		Set<byte[]> bs=jedis.zrevrange(key.getBytes(), start, end);
		Iterator<byte[]> bi=bs.iterator();
		List<T> dataList=new ArrayList<T>();
		while(bi.hasNext()){
			byte[]b=bi.next();
			T e=objTranscoder.deserialize(b);
			dataList.add(e);
		}
		return dataList;
	}
	public List<T> zrevrange(String key,long start,long end,int dataSize){
		Set<byte[]> bs=jedis.zrevrange(key.getBytes(), start, end);
		Iterator<byte[]> bi=bs.iterator();
		List<T> dataList=new ArrayList<T>();
		int i=0;
		while(bi.hasNext()&&i<dataSize){
			byte[]b=bi.next();
			T e=objTranscoder.deserialize(b);
			dataList.add(e);
			i++;
		}
		return dataList;
	}
	

	/**
	 * 建立连接池 真实环境，一般把配置参数缺抽取出来。
	 * 
	 */
	private static void createJedisPool() {

		// 建立连接池配置参数
		JedisPoolConfig config = new JedisPoolConfig();

		// 设置最大连接数
		config.setMaxTotal(100);

		// 设置最大阻塞时间，记住是毫秒数milliseconds
		config.setMaxWaitMillis(1000);

		// 设置空间连接
		config.setMaxIdle(10);

		// 创建连接池
		pool = new JedisPool(config, "127.0.0.1", 6379);

	}

	/**
	 * 在多线程环境同步初始化
	 */
	private static synchronized void poolInit() {
		if (pool == null)
			createJedisPool();
	}

	/**
	 * 
	 * 获取一个jedis 对象
	 * 
	 * @return
	 */
	public static Jedis getJedis() {

		if (pool == null)
			poolInit();
		return pool.getResource();
	}

	/**
	 * 归还一个连接
	 * 
	 * @param jedis
	 */
	public static void returnRes(Jedis jedis) {
		pool.returnResource(jedis);
	}

}
